//++
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// Module Name:
//
//    NotificationRulesContainer.cs
//
// Abstract:
//    
//    A WinForm control which houses the property page.
//
//--

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.OfficeCommunicationsServer.Applications.Common;
using Outlook = Microsoft.Office.Interop.Outlook;

namespace Microsoft.EnhancedReminders.OutlookAddIn
{
    /// <summary>
    /// Implements the Outlook property page interface as a Winform control.  The control
    /// needs to be COM visible in order to work.
    /// </summary>
    [ComVisible(true)]
    public partial class NotificationRulesContainer : UserControl, Outlook.PropertyPage
    {
        Outlook.PropertyPageSite _propertyPageSite;

        /// <summary>
        /// Constructor.
        /// </summary>
        public NotificationRulesContainer()
        {
            InitializeComponent();

            this.Load += NotificationRulesContainer_Load;
        }

        /// <summary>
        /// Fired when the property page is loaded and PropertyPageSite becomes available.
        /// </summary>
        private void NotificationRulesContainer_Load(object sender, EventArgs e)
        {
            // Use reflection to obtain the property page site.  This is not ideal but appears to be the only way to access this object.
            Type type = typeof(UserControl);
            Type oleType = type.Assembly.GetType("System.Windows.Forms.UnsafeNativeMethods+IOleObject");
            if (oleType == null)
            {
                Debug.Fail("Failed to get OLE object");
                throw new InvalidOperationException("Could not get 'System.Windows.Forms.UnsafeNativeMethods+IOleObject'.");
            }

            System.Reflection.MethodInfo method = oleType.GetMethod("GetClientSite");
            if (method == null)
            {
                Debug.Fail("Failed to get method IOleObject.GetClientSite()");
                throw new InvalidOperationException("Could not get method 'IOleObject.GetClientSite'.");
            }

            _propertyPageSite = Helpers.AssertCast<Outlook.PropertyPageSite>(method.Invoke(this, null));

            Debug.Assert(notificationRulesPropertyPage1 != null, "notificationRulesPropertyPage1");
            Debug.Assert(notificationRulesPropertyPage1.channelControl != null, "notificationRulesPropertyPage1.channelControl");

            notificationRulesPropertyPage1.channelControl.PropertyChanged += PropertyChanged;
        }

        /// <summary>
        /// Fired when the channel list has been modified by the user, allowing us to
        /// enable the "Apply" button for saving the updated channels.
        /// </summary>
        private void PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            Debug.Assert(e != null, "e");
            Debug.Assert(_propertyPageSite != null, "_propertyPageSite");

            if (e.PropertyName != "Channels")
            {
                return;
            }

            // Enables the "Apply" button and causes "OK" to apply changes.  Outlook
            // grays out the "Apply" button when it's clicked so we need to keep
            // listening for PropertyChanged events that could occur if the user makes
            // further changes after pressing "Apply".
            _propertyPageSite.OnStatusChange();
        }

        /// <summary>
        /// The property page title.  The dispatch ID attribute is required for COM to access
        /// this property.
        /// </summary>
        [DispId(-518)]
        public string Title
        {
            get
            {
                return Properties.Resources.PropertyPageTitle;
            }
        }

        #region PropertyPage Members

        /// <summary>
        /// Called by Outlook when the user requests changes to be applied to the property page (by
        /// clicking "OK" or "Apply").
        /// </summary>
        public void Apply()
        {
            Debug.Assert(notificationRulesPropertyPage1 != null, "notificationRulesPropertyPage1");

            notificationRulesPropertyPage1.SaveChannels();
        }

        /// <summary>
        /// Called by Outlook to query if a property page has changed.  This is only ever called in 
        /// response to us notifying Outlook that the page has changed (by calling OnStatusChange() on
        /// the PropertyPageSite object) which we never do so we never expect this property to be called.
        /// </summary>
        public bool Dirty
        {
            get 
            {
                return true;
            }
        }

        /// <summary>
        /// Returns help information for the property page.
        /// </summary>
        public void GetPageInfo(ref string HelpFile, ref int HelpContext)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
